package com.laundry.shared.sync

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import androidx.work.*
import com.laundry.shared.database.AppDatabase
import com.laundry.shared.network.ApiService
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import java.util.*
import java.util.concurrent.TimeUnit

/**
 * 离线数据同步管理器
 */
class OfflineSyncManager(
    private val context: Context,
    private val database: AppDatabase,
    private val apiService: ApiService
) {
    
    private val workManager = WorkManager.getInstance(context)
    private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    
    /**
     * 初始化同步服务
     */
    fun initializeSyncService() {
        // 设置定期同步任务
        schedulePeriodicSync()
        
        // 设置网络恢复时的同步任务
        scheduleNetworkRecoverySync()
        
        // 设置数据变更时的同步任务
        scheduleDataChangeSync()
    }
    
    /**
     * 检查网络连接状态
     */
    fun isNetworkAvailable(): Boolean {
        val network = connectivityManager.activeNetwork ?: return false
        val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
        
        return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
    }
    
    /**
     * 手动触发同步
     */
    suspend fun triggerManualSync(): Flow<SyncResult> = flow {
        emit(SyncResult.Loading)
        
        if (!isNetworkAvailable()) {
            emit(SyncResult.Error("网络连接不可用"))
            return@flow
        }
        
        try {
            // 同步用户数据
            val userSyncResult = syncUserData()
            if (!userSyncResult.success) {
                emit(SyncResult.Error("用户数据同步失败: ${userSyncResult.error}"))
                return@flow
            }
            
            // 同步订单数据
            val orderSyncResult = syncOrderData()
            if (!orderSyncResult.success) {
                emit(SyncResult.Error("订单数据同步失败: ${orderSyncResult.error}"))
                return@flow
            }
            
            // 同步收藏数据
            val favoriteSyncResult = syncFavoriteData()
            if (!favoriteSyncResult.success) {
                emit(SyncResult.Error("收藏数据同步失败: ${favoriteSyncResult.error}"))
                return@flow
            }
            
            // 同步评价数据
            val reviewSyncResult = syncReviewData()
            if (!reviewSyncResult.success) {
                emit(SyncResult.Error("评价数据同步失败: ${reviewSyncResult.error}"))
                return@flow
            }
            
            // 同步设置数据
            val settingsSyncResult = syncSettingsData()
            if (!settingsSyncResult.success) {
                emit(SyncResult.Error("设置数据同步失败: ${settingsSyncResult.error}"))
                return@flow
            }
            
            // 更新最后同步时间
            updateLastSyncTime()
            
            emit(SyncResult.Success("数据同步完成"))
            
        } catch (e: Exception) {
            emit(SyncResult.Error("同步过程中发生异常: ${e.message}"))
        }
    }
    
    /**
     * 获取同步状态
     */
    suspend fun getSyncStatus(): Flow<SyncStatus> = flow {
        try {
            val lastSyncTime = getLastSyncTime()
            val pendingChanges = getPendingChangesCount()
            val isOnline = isNetworkAvailable()
            
            val status = SyncStatus(
                lastSyncTime = lastSyncTime,
                pendingChanges = pendingChanges,
                isOnline = isOnline,
                isSyncing = isSyncInProgress(),
                nextScheduledSync = getNextScheduledSyncTime()
            )
            
            emit(status)
            
        } catch (e: Exception) {
            emit(SyncStatus(
                lastSyncTime = null,
                pendingChanges = 0,
                isOnline = false,
                isSyncing = false,
                nextScheduledSync = null
            ))
        }
    }
    
    /**
     * 添加待同步的数据变更
     */
    fun addPendingChange(change: DataChange) {
        try {
            database.syncDao().insertPendingChange(change.toEntity())
        } catch (e: Exception) {
            // 记录错误但不抛出异常
        }
    }
    
    /**
     * 获取离线缓存数据
     */
    suspend fun getCachedData(dataType: String, key: String): Flow<String?> = flow {
        try {
            val cachedData = database.cacheDao().getCachedData(dataType, key)
            emit(cachedData?.data)
        } catch (e: Exception) {
            emit(null)
        }
    }
    
    /**
     * 保存数据到离线缓存
     */
    suspend fun saveCachedData(dataType: String, key: String, data: String) {
        try {
            val cacheEntity = CacheEntity(
                dataType = dataType,
                key = key,
                data = data,
                timestamp = System.currentTimeMillis(),
                expiryTime = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(7) // 7天过期
            )
            database.cacheDao().insertCachedData(cacheEntity)
        } catch (e: Exception) {
            // 记录错误但不抛出异常
        }
    }
    
    /**
     * 清理过期缓存
     */
    suspend fun cleanExpiredCache() {
        try {
            val currentTime = System.currentTimeMillis()
            database.cacheDao().deleteExpiredCache(currentTime)
        } catch (e: Exception) {
            // 记录错误但不抛出异常
        }
    }
    
    // 私有方法
    private fun schedulePeriodicSync() {
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresBatteryNotLow(true)
            .build()
        
        val periodicSyncRequest = PeriodicWorkRequestBuilder<PeriodicSyncWorker>(
            15, TimeUnit.MINUTES // 每15分钟同步一次
        )
            .setConstraints(constraints)
            .setBackoffCriteria(
                BackoffPolicy.EXPONENTIAL,
                WorkRequest.MIN_BACKOFF_MILLIS,
                TimeUnit.MILLISECONDS
            )
            .build()
        
        workManager.enqueueUniquePeriodicWork(
            "periodic_sync",
            ExistingPeriodicWorkPolicy.KEEP,
            periodicSyncRequest
        )
    }
    
    private fun scheduleNetworkRecoverySync() {
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
        
        val networkRecoveryRequest = OneTimeWorkRequestBuilder<NetworkRecoverySyncWorker>()
            .setConstraints(constraints)
            .build()
        
        workManager.enqueueUniqueWork(
            "network_recovery_sync",
            ExistingWorkPolicy.REPLACE,
            networkRecoveryRequest
        )
    }
    
    private fun scheduleDataChangeSync() {
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
        
        val dataChangeSyncRequest = OneTimeWorkRequestBuilder<DataChangeSyncWorker>()
            .setConstraints(constraints)
            .setInitialDelay(5, TimeUnit.SECONDS) // 5秒后执行
            .build()
        
        workManager.enqueueUniqueWork(
            "data_change_sync",
            ExistingWorkPolicy.REPLACE,
            dataChangeSyncRequest
        )
    }
    
    private suspend fun syncUserData(): SyncOperationResult {
        return try {
            // 获取本地待同步的用户数据变更
            val pendingUserChanges = database.syncDao().getPendingChangesByType("user")
            
            // 上传本地变更到服务器
            pendingUserChanges.forEach { change ->
                when (change.operation) {
                    "UPDATE" -> {
                        // 上传用户信息更新
                        val result = apiService.syncUserUpdate(change.data)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                    "DELETE" -> {
                        // 处理用户数据删除
                        val result = apiService.syncUserDelete(change.entityId)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                }
            }
            
            // 从服务器下载最新用户数据
            val serverUserData = apiService.getUserSyncData()
            if (serverUserData.isSuccess && serverUserData.data != null) {
                // 更新本地用户数据
                database.userDao().updateUserFromSync(serverUserData.data)
            }
            
            SyncOperationResult(true)
            
        } catch (e: Exception) {
            SyncOperationResult(false, e.message)
        }
    }
    
    private suspend fun syncOrderData(): SyncOperationResult {
        return try {
            // 同步订单数据的逻辑
            val pendingOrderChanges = database.syncDao().getPendingChangesByType("order")
            
            pendingOrderChanges.forEach { change ->
                when (change.operation) {
                    "CREATE" -> {
                        val result = apiService.syncOrderCreate(change.data)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                    "UPDATE" -> {
                        val result = apiService.syncOrderUpdate(change.data)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                }
            }
            
            // 下载最新订单数据
            val serverOrderData = apiService.getOrderSyncData()
            if (serverOrderData.isSuccess && serverOrderData.data != null) {
                database.orderDao().updateOrdersFromSync(serverOrderData.data)
            }
            
            SyncOperationResult(true)
            
        } catch (e: Exception) {
            SyncOperationResult(false, e.message)
        }
    }
    
    private suspend fun syncFavoriteData(): SyncOperationResult {
        return try {
            // 同步收藏数据的逻辑
            val pendingFavoriteChanges = database.syncDao().getPendingChangesByType("favorite")
            
            pendingFavoriteChanges.forEach { change ->
                when (change.operation) {
                    "ADD" -> {
                        val result = apiService.syncFavoriteAdd(change.data)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                    "REMOVE" -> {
                        val result = apiService.syncFavoriteRemove(change.entityId)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                }
            }
            
            // 下载最新收藏数据
            val serverFavoriteData = apiService.getFavoriteSyncData()
            if (serverFavoriteData.isSuccess && serverFavoriteData.data != null) {
                database.favoriteDao().updateFavoritesFromSync(serverFavoriteData.data)
            }
            
            SyncOperationResult(true)
            
        } catch (e: Exception) {
            SyncOperationResult(false, e.message)
        }
    }
    
    private suspend fun syncReviewData(): SyncOperationResult {
        return try {
            // 同步评价数据的逻辑
            val pendingReviewChanges = database.syncDao().getPendingChangesByType("review")
            
            pendingReviewChanges.forEach { change ->
                when (change.operation) {
                    "CREATE" -> {
                        val result = apiService.syncReviewCreate(change.data)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                    "UPDATE" -> {
                        val result = apiService.syncReviewUpdate(change.data)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                }
            }
            
            SyncOperationResult(true)
            
        } catch (e: Exception) {
            SyncOperationResult(false, e.message)
        }
    }
    
    private suspend fun syncSettingsData(): SyncOperationResult {
        return try {
            // 同步设置数据的逻辑
            val pendingSettingsChanges = database.syncDao().getPendingChangesByType("settings")
            
            pendingSettingsChanges.forEach { change ->
                when (change.operation) {
                    "UPDATE" -> {
                        val result = apiService.syncSettingsUpdate(change.data)
                        if (result.isSuccess) {
                            database.syncDao().deletePendingChange(change.id)
                        }
                    }
                }
            }
            
            SyncOperationResult(true)
            
        } catch (e: Exception) {
            SyncOperationResult(false, e.message)
        }
    }
    
    private fun updateLastSyncTime() {
        val prefs = context.getSharedPreferences("sync_prefs", Context.MODE_PRIVATE)
        prefs.edit().putLong("last_sync_time", System.currentTimeMillis()).apply()
    }
    
    private fun getLastSyncTime(): Date? {
        val prefs = context.getSharedPreferences("sync_prefs", Context.MODE_PRIVATE)
        val lastSyncTime = prefs.getLong("last_sync_time", 0)
        return if (lastSyncTime > 0) Date(lastSyncTime) else null
    }
    
    private suspend fun getPendingChangesCount(): Int {
        return try {
            database.syncDao().getPendingChangesCount()
        } catch (e: Exception) {
            0
        }
    }
    
    private fun isSyncInProgress(): Boolean {
        val workInfos = workManager.getWorkInfosForUniqueWork("periodic_sync").get()
        return workInfos.any { it.state == WorkInfo.State.RUNNING }
    }
    
    private fun getNextScheduledSyncTime(): Date? {
        // 计算下次定期同步时间
        val lastSyncTime = getLastSyncTime()
        return if (lastSyncTime != null) {
            Date(lastSyncTime.time + TimeUnit.MINUTES.toMillis(15))
        } else {
            null
        }
    }
}

// 数据模型
data class SyncStatus(
    val lastSyncTime: Date?,
    val pendingChanges: Int,
    val isOnline: Boolean,
    val isSyncing: Boolean,
    val nextScheduledSync: Date?
)

sealed class SyncResult {
    object Loading : SyncResult()
    data class Success(val message: String) : SyncResult()
    data class Error(val message: String) : SyncResult()
}

data class SyncOperationResult(
    val success: Boolean,
    val error: String? = null
)

data class DataChange(
    val id: String = UUID.randomUUID().toString(),
    val dataType: String,
    val entityId: String,
    val operation: String, // CREATE, UPDATE, DELETE
    val data: String,
    val timestamp: Long = System.currentTimeMillis()
) {
    fun toEntity(): PendingChangeEntity {
        return PendingChangeEntity(
            id = id,
            dataType = dataType,
            entityId = entityId,
            operation = operation,
            data = data,
            timestamp = timestamp
        )
    }
}

// 数据库实体
data class PendingChangeEntity(
    val id: String,
    val dataType: String,
    val entityId: String,
    val operation: String,
    val data: String,
    val timestamp: Long
)

data class CacheEntity(
    val dataType: String,
    val key: String,
    val data: String,
    val timestamp: Long,
    val expiryTime: Long
)

// Worker类
class PeriodicSyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        // 执行定期同步
        return Result.success()
    }
}

class NetworkRecoverySyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        // 执行网络恢复同步
        return Result.success()
    }
}

class DataChangeSyncWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        // 执行数据变更同步
        return Result.success()
    }
}
